#pragma once

#include <AVUIAnimatable.h>

namespace AVUI {

class Transform;

class GeometryBuilder;
class PathGeometry;

class Geometry : public Animatable
{
    friend class RenderData;
public:
    DECLARE_ELEMENT(Geometry, Animatable);

    DECLARE_DEPENDENCY_PROPERTY(Transform);
    TRefCountedPtr<Transform> get_Transform() { return (Transform*)(Object*)GetValue(get_TransformProperty()); }
    void set_Transform(Transform* pValue) { SetValue(get_TransformProperty(), (Object*)pValue); } 

    virtual void BuildGeometry(GeometryBuilder* pGeometry) = 0;

    virtual Rect GetBounds() = 0;
    virtual bool HitTest(const Point& pt, int hitTestFlags, float strokeThickness) = 0;

    static TRefCountedPtr<PathGeometry> Combine(Geometry* pGeometry1, Geometry* pGeometry2, GeometryCombineMode::Enum mode, Transform* pTransform) { return NULL; }

private:
    static void StaticConstructor();

};

class StreamGeometryContext;
class GeometryTypeConverter : public TypeConverter
{
    virtual bool CanConvertFrom(Object* pContext, const Type& type) const;
    virtual ObjectPtr ConvertFrom(Object* pContext, Object* pObjectFrom) const;
    virtual bool CanConvertTo(Object* pContext, const Type& type) const { return false; };
    virtual ObjectPtr ConvertTo(Object* pContext, Object* pObjectFrom, const Type& type) const { LibraryCriticalError(); return NULL; }

private:
    static TRefCountedPtr<Geometry> ParseGeometry(const String& pathString);
    static void ParseStringToStreamGeometryContext(StreamGeometryContext* pContext, const String& pathString, FillRule::Enum* pFillRule);

};


}; // namespace AVUI
